package com.atguigu.gmall.cart.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.cart.mapper.CartInfoMapper;
import com.atguigu.gmall.cart.service.CartAsyncService;
import com.atguigu.gmall.cart.service.CartInfoService;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.product.feign.ProductFeign;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 搭忆长安
 * @version 1.0
 * @date 2021年07月09日 16:53
 * @ClassName:CartServiceImpl
 * @Description: TODO
 */
@Service
public class CartServiceImpl implements CartInfoService {
    @Autowired
    private CartInfoMapper cartInfoMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ProductFeign productFeign;
    @Autowired
    private CartAsyncService cartAsyncService;

    /**
     * 登录用户新增购物车
     * @param skuId
     * @param num
     * @param userId
     */
    @Override
    public void addCart(Long skuId, Integer num, String userId) {
     //参数
        if(skuId==null||num==null|| StringUtils.isEmpty(userId)){
            throw  new RuntimeException("参数错误");
        }
        //查询购物车的数据
        List<CartInfo> cartInfoList = cartInfoMapper.selectList(new LambdaQueryWrapper<CartInfo>()
                .eq(CartInfo::getUserId, userId).eq(CartInfo::getSkuId, skuId)
        );
        //判断是否为临时用户新增购物车
        if(cartInfoList.isEmpty()){
            //新增--购物车中没有这个商品
            CartInfo cartInfo = buildCartInfo(userId,skuId,num);
            //数据库新增
            cartAsyncService.add(cartInfo);
            //redis新增
            redisDataUpdate(cartInfo);
        }else{
            //修改的情况--购物车有这种商品，进行数量的累加
            for (CartInfo cartInfo : cartInfoList) {
                //判断当前的商品数据是否已经在购物车中
                if(cartInfo.getSkuId().equals(skuId)){
                    //进行数量的累加
                    cartInfo.setSkuNum(cartInfo.getSkuNum()+num);
                    //更新到数据库中去
                    cartAsyncService.update(cartInfo);
                    //更新redis中的数据
                    redisDataUpdate(cartInfo);
                    break;
                }
            }
        }
    }

    /**
     * 临时用户新增购物车
     * @param skuId
     * @param num
     * @param userId
     * @return
     */
    @Override
    public String addCartTemp(Long skuId, Integer num, String userId) {
        //参数判断
        if(skuId==null||num==null){
            throw  new RuntimeException("参数错误");
        }
        //判断临时用户是否为空
        if(StringUtils.isEmpty(userId)){
            //新增购物车
            userId = UUID.randomUUID().toString().replace("-", "");
            //新增购物车中没有这个商品
            CartInfo cartInfo=buildCartInfo(userId,skuId,num);
            //新增购物车数据--临时用户
            redisDataUpdate(cartInfo);
        }else{
            //修改购物车
            String cartInfoString = (String)stringRedisTemplate.boundHashOps(userId).get(RedisConst.SKUKEY_PREFIX + skuId);
            if(!StringUtils.isEmpty(cartInfoString)){
                //累加数据
                CartInfo cartInfo = JSONObject.parseObject(cartInfoString, CartInfo.class);
                cartInfo.setSkuNum(cartInfo.getSkuNum() + num);
                redisDataUpdate(cartInfo);
            }else{
                //直接添加
                CartInfo cartInfo=buildCartInfo(userId,skuId,num);
                redisDataUpdate(cartInfo);
            }
        }
        return userId;
    }
    /**
     * 删除购物车数据
     *
     * @param userId
     * @param skuId
     */
    @Override
    public void deleteCart(Long userId, Long skuId) {
        //删除数据库的数据
        cartInfoMapper.delete(
                new LambdaQueryWrapper<CartInfo>().eq(CartInfo::getUserId, userId).eq(CartInfo::getSkuId, skuId));
        //删除redis的数据
        stringRedisTemplate.boundHashOps(userId + "").delete(RedisConst.SKUKEY_PREFIX + skuId);

    }

    /**
     * 查询购物车信息
     * @param userId
     * @param tempUserId
     * @return
     */
    @Override
    public List<CartInfo> getCartInfoList(String userId/*已登录的用户id*/, String tempUserId/*临时用户的id*/) {
        //都为空
        if(StringUtils.isEmpty(userId)&&StringUtils.isEmpty(tempUserId)){
            return  null;
        }
        //参数校验--情况--临时用户有值
        if(StringUtils.isEmpty(userId)&&!StringUtils.isEmpty(tempUserId)){
            List<Object> values = stringRedisTemplate.boundHashOps(tempUserId).values();
            return  values.stream().map(c->{
                CartInfo cartInfo = JSONObject.parseObject(c.toString(), CartInfo.class);
                return  cartInfo;
            }).collect(Collectors.toList());
        }
        //判断userid是否为空，不为空查询登录用户购物车数据--购物车1
        List<CartInfo> userCartList = new ArrayList<>();
        if(!StringUtils.isEmpty(userId)){
            //查询redis的购物车数据
            List<Object> values = stringRedisTemplate.boundHashOps(userId).values();
            //redis没有值则查询数据库的数据，并存入redis
            if(values.isEmpty()){
                userCartList = cartInfoMapper.selectList(new LambdaQueryWrapper<CartInfo>().eq(CartInfo::getUserId, userId));
              if(!userCartList.isEmpty()){
                  //缓存到redis中去
                  for (CartInfo cartInfo : userCartList) {
                      stringRedisTemplate.boundHashOps(userId).put(RedisConst.SKUKEY_PREFIX + cartInfo.getSkuId(),JSONObject.toJSONString(cartInfo));
                  }
              }
            }else{
                userCartList = values.stream().map(c->{
                    CartInfo cartInfo = JSONObject.parseObject(c.toString(), CartInfo.class);
                    return cartInfo;
                }).collect(Collectors.toList());
            }
        }
        //判断临时userId是否为空，查询临时用户的购物车数据--购物车2
        List<CartInfo> tempUserCartList = new ArrayList<>();
        if(!StringUtils.isEmpty(tempUserId)){
            //查询redis购物车数据
            List<Object> values = stringRedisTemplate.boundHashOps(tempUserId).values();
            if(!values.isEmpty()){
                values.stream().map(c->{
                    CartInfo cartInfo = JSONObject.parseObject(c.toString(), CartInfo.class);
                    return cartInfo;
                }).collect(Collectors.toList());
            }
        }
        //如果购物车1不为空，购物车2不为空--合并--删除临时用户的购物车数据
        if(!tempUserCartList.isEmpty() && !userCartList.isEmpty()){
            //两个都不为空的情况下
            for (CartInfo cartInfo: tempUserCartList) {
                CartInfo o = cartInfoMapper.selectOne(new LambdaQueryWrapper<CartInfo>()
                        .eq(CartInfo::getSkuId, cartInfo.getSkuId())
                        .eq(CartInfo::getUserId, userId));
                if(o != null){
                    //数量合并
                    o.setSkuNum(cartInfo.getSkuNum() + o.getSkuNum());
                    //存入数据库
                    cartInfoMapper.updateById(o);
                }else{
                    cartInfo.setUserId(userId);
                    cartInfoMapper.insert(cartInfo);
                }
                //删除redis中的当前购车数据
                stringRedisTemplate.boundHashOps(tempUserId).delete(RedisConst.SKUKEY_PREFIX + cartInfo.getSkuId());
            }
            //清除当前所有的旧的登录用户的购物车数据
            stringRedisTemplate.delete(userId);
            return cartInfoMapper.selectList(new LambdaQueryWrapper<CartInfo>().eq(CartInfo::getUserId,userId));
        }else if(tempUserCartList.isEmpty()&&!userCartList.isEmpty()){
            //临时用户的购物车为空 登录用户的购物车有值
            return  userCartList;
        }else if(!tempUserCartList.isEmpty()&&userCartList.isEmpty()){

            //临时用户的购物测有值 登录用户的购物车为空
            //将临时用户的购物车数据insert到数据库--删除临时用户的购物车数据
            for (CartInfo cartInfo : tempUserCartList) {
                cartInfo.setUserId(userId);
                cartInfoMapper.insert(cartInfo);
            }
            stringRedisTemplate.delete(tempUserId);
            return tempUserCartList;
        }
        //返回数据
        return null;
    }

    @Override
    public void editCart(Long skuId, Integer num,String userId) {
        if(skuId==null||num==null|| StringUtils.isEmpty(userId)){
            throw  new RuntimeException("参数错误");
        }
        //删除购物车数据,条件: userid= 登录用户 and skuid=等当前要更新的skuid
        cartInfoMapper.delete(new LambdaQueryWrapper<CartInfo>().eq(CartInfo::getUserId,userId).eq(CartInfo::getSkuId,skuId));
        //覆盖redis中的旧的数据
        stringRedisTemplate.boundHashOps(userId).delete(RedisConst.SKUKEY_PREFIX + skuId);
        //新增
        CartInfo cartInfo=buildCartInfo(userId,skuId,num);
        cartAsyncService.add(cartInfo);
        redisDataUpdate(cartInfo);
    }

    @Override
    public void editCartTemp(Long skuId, Integer num,String userId) {
        if(skuId==null||num==null|| StringUtils.isEmpty(userId)){
            throw  new RuntimeException("参数错误");
        }
        //查询redis中的数据
         List<Object> values = stringRedisTemplate.boundHashOps(userId).values();
        //更新数据

        //覆盖数据

    }

    /**
     * 查询用户选中的购物车信息
     *
     * @param userId
     * @return
     */
    @Override
    public List<CartInfo> getChooseCartInfoList(Long userId) {
        return cartInfoMapper.selectList(
                new LambdaQueryWrapper<CartInfo>()
                        .eq(CartInfo::getUserId, userId)
                        .eq(CartInfo::getIsChecked, 1));
    }

    @Override
    public Map<String, Object> getChooseCartInfo(Long userId) {
        //查询所有选中的购物车信息
        List<CartInfo> cartInfoList = cartInfoMapper.selectList(
                new LambdaQueryWrapper<CartInfo>()
                        .eq(CartInfo::getUserId, userId)
                        .eq(CartInfo::getIsChecked, 1));
        //遍历计算
        BigDecimal total = new BigDecimal(0);
        int numTotal = 0;
        for (CartInfo cartInfo : cartInfoList) {
            BigDecimal price = productFeign.getPrice(cartInfo.getSkuId());
            total = total.add(price.multiply(new BigDecimal(cartInfo.getSkuNum())));
            numTotal += cartInfo.getSkuNum();
        }
        //保存
        Map<String, Object> map = new HashMap<>();
        map.put("numTotal", numTotal);
        map.put("total", total);
        map.put("cartInfoList", cartInfoList);
        //返回结果
        return map;
    }

    /**
     * 构建购物车对象实体
     * @param userId
     * @param skuId
     * @param num
     * @return
     */
    private CartInfo buildCartInfo(String userId, Long skuId, Integer num) {
     //新增--购物车中没有这个商品
        CartInfo cartInfo = new CartInfo();
        cartInfo.setUserId(userId);
        cartInfo.setSkuId(skuId);
        BigDecimal price = productFeign.getPrice(skuId);
        cartInfo.setCartPrice(price);
        cartInfo.setSkuNum(num);
        SkuInfo skuInfo = productFeign.getSkuInfo(skuId);
        cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
        cartInfo.setSkuName(skuInfo.getSkuName());
        cartInfo.setIsChecked(1);
        //返回结果
        return  cartInfo;
    }

    /**
     * 更新redis的数据
     * @param cartInfo
     */
    private void redisDataUpdate(CartInfo cartInfo){
        stringRedisTemplate.boundHashOps(cartInfo.getUserId()).put(RedisConst.SKUKEY_PREFIX + cartInfo.getSkuId(),JSONObject.toJSONString(cartInfo));
    }
}
